﻿using DevExpress.XtraEditors;
using DevExpress.XtraPrinting.Native;
using MesProjectWinform.Helper;
using MesProjectWinform.Public;
using MesProjectWinform.Public.Common;
using MesProjectWinform.WareHouse.Common;
using MesProjectWinform.WareHouse.Entity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MesProjectWinform.WareHouse.Form.数据维护
{
    public partial class Form_AddJob : DevExpress.XtraEditors.XtraForm
    {
        public Form_AddJob()
        {
            InitializeComponent();
        }

        public bool UpdateType = false;

        // 使用JobModel类来接收数据
        public JobModel Current { get; set; }

        private async void Form_AddDep_Load(object sender, EventArgs e)
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                if (UpdateType)
                {
                    // 新增模式
                    this.Text = "新增职位";
                    btnAdd.Text = "新增";

                    // 直接异步获取编码并设置到文本框
                    string code = await GetCode();
                    txtCode.Text = code;
                    textJob.Text = Current.SuperiorJobName;
                    textDep.Text = Current.DepName;
                    // 启用状态默认为是
                    toggleIsEnable.IsOn = true;
                }
                else
                {
                    // 修改模式
                    this.Text = "修改职位";
                    btnAdd.Text = "保存";

                    // 绑定传入的数据到控件
                    if (Current != null)
                    {
                        // 填充表单控件
                        txtCode.Text = Current.JobId;
                        txtName.Text = Current.JobName;
                        textJob.Text = Current.SuperiorJobName;
                        textDep.Text = Current.DepName;
                        toggleIsEnable.IsOn = Current.IsEnable;

                    }
                }

                // 手动触发下拉框值改变事件，确保选中项显示正确
                //lookUpSupplier.RefreshEditValue();
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载窗体时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        private async void btnAdd_Click(object sender, EventArgs e)
        {

            // 防止重复点击
            btnAdd.Enabled = false;
            btnCancel.Enabled = false;

            // 记录操作开始时间，用于防止重复提交
            string requestId = Guid.NewGuid().ToString();

            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;
                HttpClientHelper helper = new HttpClientHelper();
                // 检查必填字段是否有值
                string errorMessage = Check();
                if (!string.IsNullOrEmpty(errorMessage))
                {
                    MessageBox.Show(errorMessage, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 验证编码是否已被占用（并发检查）
                bool isCodeAvailable = await CheckCodeAvailability(txtCode.Text.Trim());
                if (!isCodeAvailable && UpdateType) // 只在新增模式下检查
                {
                    MessageBox.Show("职位编码已被占用，请刷新后重试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                JobModel model = new JobModel();

                // 如果是修改模式，使用传入对象的ID和创建信息
                if (!UpdateType && Current != null)
                {
                    model.JobId = Current.JobId;
                    model.CreatedBy = Current.CreatedBy;
                    model.CreatedTime = Current.CreatedTime;
                    model.UpdatedTime = DateTime.Now;
                }
                else
                {
                    // 新增模式，初始化创建信息
                    model.CreatedTime = DateTime.Now;
                    model.CreatedBy = RequestUser.CurrentUser.UserId;//"00";
                    model.UpdatedTime = DateTime.Now;
                    model.JobId = txtCode.Text.Trim();
                }

                // 设置基本信息
                model.JobName = txtName.Text.Trim();
                model.SuperiorJobID = Current.SuperiorJobID;
                model.DepId = Current.DepId;
                model.IsEnable = toggleIsEnable.IsOn;
                if (string.IsNullOrEmpty(model.SuperiorJobID))
                {
                    model.RankOrder = 0;
                }
                else
                {
                    string json = helper.RequestUrlNew(RequestType.Get, WareHouseGolab.GetJOBBYId+ model.SuperiorJobID, null);
                   ApiResult< JobModel> model1 = JsonConvert.DeserializeObject<ApiResult<JobModel>>(json);
                    model.RankOrder = model1.Data.RankOrder + 1;
                }
                // 将对象序列化为JSON
                string postData = JsonConvert.SerializeObject(model);

                // 添加请求ID，用于防止重复提交
                Dictionary<string, string> headers = new Dictionary<string, string>
                {
                    { "X-Request-ID", requestId },
                    { "X-Client-Timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") }
                };

                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;

                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        // 根据操作类型选择API
                        string url = UpdateType ? "WareHouse/Job/AddJob" : "WareHouse/Job/UpdatJob";
                        
                        // 使用带自定义头的请求方法
                        string json = helper.RequestUrlNew(RequestType.Post, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);

                        if (baseModel.Code == ApiEnums.Success)
                        {
                            // 更新编码记录
                            await UpdateCode();

                            string message = UpdateType ? "添加成功" : "修改成功";
                            MessageBox.Show(message, "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = DialogResult.OK;

                            // 标记成功
                            success = true;

                            // 关闭窗口
                            this.Close();
                        }
                        else
                        {
                            // 检查是否是因为并发冲突导致的失败
                            if (baseModel.Code == ApiEnums.Error)
                            {
                                retryCount++;
                                if (retryCount < maxRetries)
                                {
                                    // 等待一段时间后重试
                                    await Task.Delay(1000 * retryCount); // 逐次增加等待时间
                                    continue;
                                }
                            }

                            MessageBox.Show(baseModel.Message, "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        retryCount++;
                        if (retryCount >= maxRetries)
                        {
                            MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            break;
                        }

                        // 等待一段时间后重试
                        await Task.Delay(1000 * retryCount);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存数据时发生错误：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复按钮状态
                btnAdd.Enabled = true;
                btnCancel.Enabled = true;

                // 恢复光标
                Cursor = Cursors.Default;
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #region 自定义方法
        /// <summary>
        /// 检查必填字段
        /// </summary>
        private string Check()
        {
            List<string> emptyFields = new List<string>();

            // 检查编号
            if (string.IsNullOrWhiteSpace(txtCode.Text))
            {
                emptyFields.Add("编码");
            }

            // 检查名称
            if (string.IsNullOrWhiteSpace(txtName.Text))
            {
                emptyFields.Add("名称");
            }


            // 如果有空字段，返回错误消息
            if (emptyFields.Count > 0)
            {
                return $"添加失败，以下字段不能为空：{string.Join("、", emptyFields)}";
            }

            // 所有字段都已填写
            return string.Empty;
        }

        /// <summary>
        /// 检查编码是否可用
        /// </summary>
        private async Task<bool> CheckCodeAvailability(string code)
        {
            try
            {
                HttpClientHelper helper = new HttpClientHelper();
                // 调用API检查编码是否可用
                string url = $"WareHouse/Job/GetJobId?JobId={Uri.EscapeDataString(code)}";
                string json = helper.RequestUrlNew(RequestType.Get, url, null);
                ApiResult<bool> result = JsonConvert.DeserializeObject<ApiResult<bool>>(json);

                // 返回true表示编码可用，false表示编码已被占用
                return result.Code == ApiEnums.Success;
            }
            catch (Exception ex)
            {
                //System.Diagnostics.Debug.WriteLine($"检查编码可用性时发生异常: {ex.Message}");
                // 出现异常时，假定编码可用，让后续流程继续（后端会再次检查）
                return true;
            }
        }

        // <summary>
        /// 更新编码记录
        /// </summary>
        public async Task UpdateCode()
        {
            try
            {
                // 根据操作类型选择API
                string url = "WareHouse/BasicInfo/UpdateCode";
                TypeCodeModel model = new TypeCodeModel();
                model.Code = txtCode.Text;
                model.CodeType = DataConverHelper.GetPrefix(CodeType.Job);
                model.CodeTypeName = "职位";
                string postData = JsonConvert.SerializeObject(model);

                // 设置重试次数
                int maxRetries = 3;
                int retryCount = 0;
                bool success = false;

                while (!success && retryCount < maxRetries)
                {
                    try
                    {
                        HttpClientHelper helper = new HttpClientHelper();
                        string json = helper.RequestUrlNew(RequestType.Put, url, postData);
                        ApiResult<int> baseModel = JsonConvert.DeserializeObject<ApiResult<int>>(json);

                        if (baseModel != null && baseModel.Code == ApiEnums.Success)
                        {
                            success = true;
                            return;
                        }

                        // 如果失败，尝试重试
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                    }
                    catch (Exception ex)
                    {
                        //System.Diagnostics.Debug.WriteLine($"更新编码记录时发生异常: {ex.Message}");
                        retryCount++;
                        if (retryCount < maxRetries)
                        {
                            await Task.Delay(1000 * retryCount);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //System.Diagnostics.Debug.WriteLine($"更新编码记录失败: {ex.Message}");
                // 这里选择不抛出异常，因为即使编码记录更新失败，主业务流程已经完成
            }
        }

        /// <summary>
        /// 获取编码
        /// </summary>
        private async Task<string> GetCode()
        {
            try
            {
                // 显示等待光标
                Cursor = Cursors.WaitCursor;

                string codePrefix = DataConverHelper.GetPrefix(CodeType.Job);

                // 首先尝试直接生成一个新编码作为备选
                string fallbackCode = DataConverHelper.GenerateCode(CodeType.Job);

                // 获取互联网时间
                //DateTime internetTime = await GetInternetTime();
                ////System.Diagnostics.Debug.WriteLine($"互联网时间: {internetTime}，本地时间: {DateTime.Now}");

                try
                {
                    // 调用API获取最新编码
                    string apiUrl = "WareHouse/BasicInfo/GetCode?Type=" + codePrefix;
                    HttpClientHelper helper = new HttpClientHelper();
                    string json = helper.RequestUrlNew(RequestType.Get, apiUrl, null);

                    if (string.IsNullOrEmpty(json))
                    {
                        return fallbackCode;
                    }

                    ApiResult<TypeCodeModel> typeModel = JsonConvert.DeserializeObject<ApiResult<TypeCodeModel>>(json);

                    if (typeModel == null || typeModel.Data == null)
                    {
                        return fallbackCode;
                    }

                    string lastCode = typeModel.Data.Code;

                    if (string.IsNullOrEmpty(lastCode))
                    {
                        return fallbackCode;
                    }

                    // 获取数字部分（后五位或全部，如果不足五位）
                    string numberPart;
                    string prefixPart;

                    // 提取数字部分和前缀部分
                    if (lastCode.Length >= 5)
                    {
                        // 如果编码长度超过5位，提取最后5位作为数字部分，其余作为前缀
                        numberPart = lastCode.Substring(lastCode.Length - 5);
                        prefixPart = lastCode.Substring(0, lastCode.Length - 5);
                    }
                    else
                    {
                        // 如果编码长度不足5位，就用整个编码作为数字部分，前缀为空
                        numberPart = lastCode;
                        prefixPart = "";
                    }

                    // 尝试解析为数字并自增1
                    if (int.TryParse(numberPart, out int lastNumber))
                    {
                        // 使用互联网时间获取当前日期字符串
                        string currentDateStr = DateTime.Now.ToString("yyMMdd");
                        string dateInPrefix = "";

                        // 检查前缀中是否包含日期信息
                        if (prefixPart.Length >= 6 && prefixPart.StartsWith(codePrefix))
                        {
                            dateInPrefix = prefixPart.Substring(1, 6);
                        }

                        // 如果前缀中的日期与当前日期不同，或者前缀不合规范，则重置编号并使用新日期
                        if (string.IsNullOrEmpty(prefixPart) || !prefixPart.StartsWith(codePrefix) ||
                            (dateInPrefix != currentDateStr && !string.IsNullOrEmpty(dateInPrefix)))
                        {
                            // 新的一天，编号从1开始
                            prefixPart = codePrefix + currentDateStr;
                            lastNumber = 1; // 重置为1
                        }
                        else
                        {
                            // 同一天，编号递增
                            lastNumber++;
                        }

                        // 数字部分解析成功，确保是5位数（前面补0）
                        string fiveDigitNumber = lastNumber.ToString("D5");

                        // 组合新编码
                        string newCode = prefixPart + fiveDigitNumber;
                        return newCode;
                    }
                    else
                    {
                        return fallbackCode;
                    }
                }
                catch (Exception ex)
                {
                    //System.Diagnostics.Debug.WriteLine($"获取编码异常: {ex.Message}");
                    return fallbackCode;
                }
            }
            finally
            {
                // 恢复光标
                Cursor = Cursors.Default;
            }
        }



        #endregion
    }
}